﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;
using System.Xml;

namespace CommentHero
{
    //=======================================================================
    // クラス名：AboutBox
    /// <summary>
    /// バージョン情報・設定ダイアログ
    /// </summary>
    /// <remarks>
    /// バージョン情報及び設定ダイアログです。
    /// </remarks>
    /*=======================================================================
    更新履歴
    項番        更新日付    担当者      更新内容
    0001        2006/12/26  向山        新規作成
    =======================================================================*/
    partial class AboutBox : Form
    {
        //==============================================================
        // コンストラクタ名：AboutBox
        /// <summary>
        /// AboutBoxクラスの初期化処理を行います。
        /// </summary>
        /// <remarks>
        /// バージョン情報タブ、共通設定タブの初期化処理を行います。
        /// </remarks>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        public AboutBox()
        {
            InitializeComponent();
            cmbCommentType.SelectedIndex = 0;
            cmbLanguage.SelectedIndex = 0;

            //  アセンブリ情報からの製品情報を表示する情報ボックスを初期化します。
            //  アプリケーションのアセンブリ情報設定を次のいずれかにて変更します:
            //  - [プロジェクト] メニューの [プロパティ] にある [アプリケーション] の [アセンブリ情報]
            //  - AssemblyInfo.cs
            this.Text = String.Format("{0} のバージョン情報", AssemblyTitle);
            this.labelProductName.Text = String.Format("{0}", AssemblyProduct);
            this.labelVersion.Text = String.Format("ver {0}", AssemblyVersion);
            this.labelDescription.Text = AssemblyDescription;
            this.labelCopyright.Text = String.Format("Copyright {0}", AssemblyCopyright);

            InitializeSetting1Tab();
        }

        #region アセンブリ属性アクセサ

        public string AssemblyTitle
        {
            get
            {
                // このアセンブリ上のタイトル属性をすべて取得します
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
                // 少なくとも 1 つのタイトル属性がある場合
                if (attributes.Length > 0)
                {
                    // 最初の項目を選択します
                    AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
                    // 空の文字列の場合、その項目を返します
                    if (titleAttribute.Title != "")
                        return titleAttribute.Title;
                }
                // タイトル属性がないか、またはタイトル属性が空の文字列の場合、.exe 名を返します
                return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
            }
        }

        public string AssemblyVersion
        {
            get
            {
                return Assembly.GetExecutingAssembly().GetName().Version.ToString(2);
            }
        }

        public string AssemblyDescription
        {
            get
            {
                // このアセンブリ上の説明属性をすべて取得します
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
                // 説明属性がない場合、空の文字列を返します
                if (attributes.Length == 0)
                    return "";
                // 説明属性がある場合、その値を返します
                return ((AssemblyDescriptionAttribute)attributes[0]).Description;
            }
        }

        public string AssemblyProduct
        {
            get
            {
                // このアセンブリ上の製品属性をすべて取得します
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
                // 製品属性がない場合、空の文字列を返します
                if (attributes.Length == 0)
                    return "";
                // 製品属性がある場合、その値を返します
                return ((AssemblyProductAttribute)attributes[0]).Product;
            }
        }

        public string AssemblyCopyright
        {
            get
            {
                // このアセンブリ上の著作権属性をすべて取得します
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
                // 著作権属性がない場合、空の文字列を返します
                if (attributes.Length == 0)
                    return "";
                // 著作権属性がある場合、その値を返します
                return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
            }
        }

        public string AssemblyCompany
        {
            get
            {
                // このアセンブリ上の会社属性をすべて取得します
                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
                // 会社属性がない場合、空の文字列を返します
                if (attributes.Length == 0)
                    return "";
                // 会社属性がある場合、その値を返します
                return ((AssemblyCompanyAttribute)attributes[0]).Company;
            }
        }
        #endregion

        //==============================================================
        // メソッド名：btnOK_Click
        /// <summary>
        /// OKボタン押下イベント
        /// </summary>
        /// <remarks>
        /// 設定ファイルを保存、再読み込みします。
        /// </remarks>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        private void btnOK_Click(object sender, EventArgs e)
        {
            SaveSettings1();
            ConfigReader.SaveXml();
            ConfigReader.LoadConfig();
        }

        #region 共通設定タブ
        //==============================================================
        // メソッド名：InitializeSetting1Tab
        /// <summary>
        /// 共通設定タブの初期化処理
        /// </summary>
        /// <remarks>
        /// フォームのデフォルト項目を設定します。
        /// </remarks>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        private void InitializeSetting1Tab()
        {
            CustomCommentAttributes[] customCommentAttributes = ConfigReader.Instance.CustomCommentAttributes;
            cboxEnableCustom1.Checked = customCommentAttributes[0].Enable;
            txtCustom1Name.Text = customCommentAttributes[0].Title;
            txtCustom1Description.Text = customCommentAttributes[0].Tips;
            cboxEnableCustom2.Checked = customCommentAttributes[1].Enable;
            txtCustom2Name.Text = customCommentAttributes[1].Title;
            txtCustom2Description.Text = customCommentAttributes[1].Tips;
            cboxEnableCustom3.Checked = customCommentAttributes[2].Enable;
            txtCustom3Name.Text = customCommentAttributes[2].Title;
            txtCustom3Description.Text = customCommentAttributes[2].Tips;
            cboxEnableCustom4.Checked = customCommentAttributes[3].Enable;
            txtCustom4Name.Text = customCommentAttributes[3].Title;
            txtCustom4Description.Text = customCommentAttributes[3].Tips;
            cboxEnableCustom5.Checked = customCommentAttributes[4].Enable;
            txtCustom5Name.Text = customCommentAttributes[4].Title;
            txtCustom5Description.Text = customCommentAttributes[4].Tips;

            txtDateFormat.Text = ConfigReader.Instance.DateFormat;
            txtAuthor.Text = ConfigReader.Instance.Author;
        }

        //==============================================================
        // メソッド名：SaveSettings1
        /// <summary>
        /// 共通設定の更新
        /// </summary>
        /// <remarks>
        /// XMLドキュメントに設定の変更を反映します。
        /// </remarks>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        private void SaveSettings1()
        {
            CustomCommentAttributes[] customCommentAttributes = ConfigReader.Instance.CustomCommentAttributes;

            ConfigReader.UpdateNode("/configuration/customize/custom1", "enable", cboxEnableCustom1.Checked.ToString().ToLower());
            ConfigReader.UpdateNode("/configuration/customize/custom1", "title", txtCustom1Name.Text);
            ConfigReader.UpdateNode("/configuration/customize/custom1", "tips", txtCustom1Description.Text);

            ConfigReader.UpdateNode("/configuration/customize/custom2", "enable", cboxEnableCustom2.Checked.ToString().ToLower());
            ConfigReader.UpdateNode("/configuration/customize/custom2", "title", txtCustom2Name.Text);
            ConfigReader.UpdateNode("/configuration/customize/custom2", "tips", txtCustom2Description.Text);

            ConfigReader.UpdateNode("/configuration/customize/custom3", "enable", cboxEnableCustom3.Checked.ToString().ToLower());
            ConfigReader.UpdateNode("/configuration/customize/custom3", "title", txtCustom3Name.Text);
            ConfigReader.UpdateNode("/configuration/customize/custom3", "tips", txtCustom3Description.Text);

            ConfigReader.UpdateNode("/configuration/customize/custom4", "enable", cboxEnableCustom4.Checked.ToString().ToLower());
            ConfigReader.UpdateNode("/configuration/customize/custom4", "title", txtCustom4Name.Text);
            ConfigReader.UpdateNode("/configuration/customize/custom4", "tips", txtCustom4Description.Text);

            ConfigReader.UpdateNode("/configuration/customize/custom5", "enable", cboxEnableCustom5.Checked.ToString().ToLower());
            ConfigReader.UpdateNode("/configuration/customize/custom5", "title", txtCustom5Name.Text);
            ConfigReader.UpdateNode("/configuration/customize/custom5", "tips", txtCustom5Description.Text);

            ConfigReader.UpdateNode("/configuration/customize/dateFormat", "value", txtDateFormat.Text);
            ConfigReader.UpdateNode("/configuration/customize/author", "value", txtAuthor.Text);
        }
        #endregion

        #region コメント設定タブ
        //==============================================================
        // メソッド名：btnEdit_Click
        /// <summary>
        /// コメント設定タブの編集ボタン押下イベント
        /// </summary>
        /// <remarks>
        /// 選択されているコメント種別・言語に合わせて編集ダイアログを開きます。
        /// </remarks>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        private void btnEdit_Click(object sender, EventArgs e)
        {
            //HeaderComment target = null;
            string text = null;
            string targetNode = string.Empty;

            switch (cmbCommentType.SelectedIndex)
            {
                case 0:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditHeaderComment(ConfigReader.Instance.CSComments.ClassHeaderComment);
                        targetNode = "/configuration/cs/header/class";
                    }
                    else
                    {
                        text = EditHeaderComment(ConfigReader.Instance.VBComments.ClassHeaderComment);
                        targetNode = "/configuration/vb/header/class";
                    }
                    break;
                case 1:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditHeaderComment(ConfigReader.Instance.CSComments.InterfaceHeaderComment);
                        targetNode = "/configuration/cs/header/interface";
                    }
                    else
                    {
                        text = EditHeaderComment(ConfigReader.Instance.VBComments.InterfaceHeaderComment);
                        targetNode = "/configuration/vb/header/interface";
                    }
                    break;
                case 2:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditHeaderComment(ConfigReader.Instance.CSComments.MethodHeaderComment);
                        targetNode = "/configuration/cs/header/method";
                    }
                    else
                    {
                        text = EditHeaderComment(ConfigReader.Instance.VBComments.MethodHeaderComment);
                        targetNode = "/configuration/vb/header/method";
                    }
                    break;
                case 3:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditHeaderComment(ConfigReader.Instance.CSComments.ConstructorHeaderComment);
                        targetNode = "/configuration/cs/header/constructor";
                    }
                    else
                    {
                        text = EditHeaderComment(ConfigReader.Instance.VBComments.ConstructorHeaderComment);
                        targetNode = "/configuration/vb/header/constructor";
                    }
                    break;
                case 4:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditHeaderComment(ConfigReader.Instance.CSComments.PropertyHeaderComment);
                        targetNode = "/configuration/cs/header/property";
                    }
                    else
                    {
                        text = EditHeaderComment(ConfigReader.Instance.VBComments.PropertyHeaderComment);
                        targetNode = "/configuration/vb/header/property";
                    }
                    break;
                case 5:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditHeaderComment(ConfigReader.Instance.CSComments.TestCaseHeaderComment);
                        targetNode = "/configuration/cs/header/testcase";
                    }
                    else
                    {
                        text = EditHeaderComment(ConfigReader.Instance.VBComments.TestCaseHeaderComment);
                        targetNode = "/configuration/vb/header/testcase";
                    }
                    break;
                case 6:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditComment(ConfigReader.Instance.CSComments.BlockComment);
                        targetNode = "/configuration/cs/comment/block";
                    }
                    else
                    {
                        text = EditComment(ConfigReader.Instance.VBComments.BlockComment);
                        targetNode = "/configuration/vb/comment/block";
                    }
                    break;
                case 7:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditComment(ConfigReader.Instance.CSComments.CustomComment1);
                        targetNode = "/configuration/cs/comment/custom1";
                    }
                    else
                    {
                        text = EditComment(ConfigReader.Instance.VBComments.CustomComment1);
                        targetNode = "/configuration/vb/comment/custom1";
                    }
                    break;
                case 8:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditComment(ConfigReader.Instance.CSComments.CustomComment2);
                        targetNode = "/configuration/cs/comment/custom2";
                    }
                    else
                    {
                        text = EditComment(ConfigReader.Instance.VBComments.CustomComment2);
                        targetNode = "/configuration/vb/comment/custom2";
                    }
                    break;
                case 9:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditComment(ConfigReader.Instance.CSComments.CustomComment3);
                        targetNode = "/configuration/cs/comment/custom3";
                    }
                    else
                    {
                        text = EditComment(ConfigReader.Instance.VBComments.CustomComment3);
                        targetNode = "/configuration/vb/comment/custom3";
                    }
                    break;
                case 10:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditComment(ConfigReader.Instance.CSComments.CustomComment4);
                        targetNode = "/configuration/cs/comment/custom4";
                    }
                    else
                    {
                        text = EditComment(ConfigReader.Instance.VBComments.CustomComment4);
                        targetNode = "/configuration/vb/comment/custom4";
                    }
                    break;
                case 11:
                    if (cmbLanguage.SelectedIndex == 0)
                    {
                        text = EditComment(ConfigReader.Instance.CSComments.CustomComment5);
                        targetNode = "/configuration/cs/comment/custom5";
                    }
                    else
                    {
                        text = EditComment(ConfigReader.Instance.VBComments.CustomComment5);
                        targetNode = "/configuration/vb/comment/custom5";
                    }
                    break;
                default:
                    break;
            }

            if (!string.IsNullOrEmpty(text))
            {
                ConfigReader.UpdateNodeXml(targetNode, text);
            }
        }

        //==============================================================
        // メソッド名：EditHeaderComment
        /// <summary>
        /// ヘッダコメントの整形
        /// </summary>
        /// <remarks>
        /// コメント編集ダイアログに入力されたヘッダコメントをXML保存用に整形します。
        /// </remarks>
        /// <param name="target">編集元のヘッダコメント</param>
        /// <returns>XML保存用に整形された文字列</returns>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        private string EditHeaderComment(HeaderComment target)
        {
            CommentEditor editor = new CommentEditor(target);
            DialogResult result = editor.ShowDialog();
            if (result == DialogResult.OK)
            {
                string nodeString = string.Empty;
                foreach (string str in editor.Comment)
                {
                    nodeString += string.Format("<out>{0}</out>", EscapeXml(str));
                }

                foreach (string str in editor.Summary)
                {
                    nodeString += string.Format("<xmlsummary>{0}</xmlsummary>", EscapeXml(str));
                }

                foreach (string str in editor.Remarks)
                {
                    nodeString += string.Format("<xmlremarks>{0}</xmlremarks>", EscapeXml(str));
                }

                return nodeString;
            }
            else
            {
                return null;
            }
        }

        //==============================================================
        // メソッド名：EditHeaderComment
        /// <summary>
        /// コメントの整形
        /// </summary>
        /// <remarks>
        /// コメント編集ダイアログに入力されたコメントをXML保存用に整形します。
        /// </remarks>
        /// <param name="target">編集元のコメント</param>
        /// <returns>XML保存用に整形された文字列</returns>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        private string EditComment(List<string> target)
        {
            CommentEditor editor = new CommentEditor(target);
            DialogResult result = editor.ShowDialog();
            if (result == DialogResult.OK)
            {
                string nodeString = string.Empty;
                foreach (string str in editor.Comment)
                {
                    nodeString += string.Format("<out>{0}</out>", EscapeXml(str));
                }

                return nodeString;
            }
            else
            {
                return null;
            }
        }

        //==============================================================
        // メソッド名：EscapeXml
        /// <summary>
        /// XMLサニタイズ処理
        /// </summary>
        /// <remarks>
        /// 入力されたコメントの特殊文字を置換します。
        /// </remarks>
        /// <param name="str">検査用文字列</param>
        /// <returns>置換後文字列</returns>
        /*==============================================================
        更新履歴
        項番        更新日付    担当者      更新内容
        0001        2006/12/26  向山        新規作成
        ==============================================================*/
        private string EscapeXml(string str)
        {
            str = str.Replace("&", "&amp;");
            str = str.Replace("<", "&lt;");
            str = str.Replace(">", "&gt;");

            return str;
        }
        #endregion
    }
}
